package com.xinyue.game.client.service;

import java.io.UnsupportedEncodingException;
import java.util.zip.CRC32;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSONObject;
import com.xinyue.utils.Crc32Util;
import com.xinyue.utils.DateUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

public class CodecFactory {
	private static Logger logger = LoggerFactory.getLogger(CodecFactory.class);
	// 包头的固定长度
	private static int headLength = 27;
	// 消息序列id
	private static int seqId = 0;

	public static ByteBuf encode(JSONObject data, int messageId) throws UnsupportedEncodingException {
		byte[] body = null;
		int initialCapacity = headLength;
		if (data != null) {
			body = data.toJSONString().getBytes("utf8");
			initialCapacity += body.length;
		}
		ByteBuf bytebuf = Unpooled.buffer(initialCapacity);
		bytebuf.writeShort(initialCapacity);// 2
		bytebuf.writeInt(seqId++);// 4
		bytebuf.writeInt(messageId);// 4
		bytebuf.writeLong(System.currentTimeMillis());
	    //协议版本
		bytebuf.writeByte(1);
		// 计算crc32的值
		long crcValue = Crc32Util.crc32(body);
		if (crcValue != 0) {
			bytebuf.writeLong(crcValue);
		}
		if (body != null) {
			bytebuf.writeBytes(body);
		}
		return bytebuf;
	}

	
	private static boolean checkCrc(long crcValue, byte[] body) {
		return true;
	}

	private static byte[] unzip(byte[] body) {
		return body;
	}

	public static String decode(ByteBuf byteBuf) {
		//读取消息头
		short total = byteBuf.readShort();
		int seqId = byteBuf.readInt();
		int messageId = byteBuf.readInt();
		long serverTime = byteBuf.readLong();
		byte isZip = byteBuf.readByte();
		int errorCode = byteBuf.readInt();
		logger.info("收到服务器消息：total:{},seqId:{},messageId:{},serverTime:{},errorCode:{}", total, seqId, messageId,
				DateUtil.formatDate(serverTime), errorCode);
		long crcValue = byteBuf.readLong();
		//读取消息体
		if (errorCode == 0 && byteBuf.readableBytes() > 0) {
			
			byte[] body = new byte[byteBuf.readableBytes()];
			byteBuf.readBytes(body);
			//检测crc是否正确
			if (!checkCrc(crcValue, body)) {
				throw new IllegalArgumentException("服务器返回的消息错误,crc验证失败");
			}
			//判断是否是压缩消息
			if (isZip == 1) {
				body = unzip(body);
			}
			// 这里暂时使用json做为消息体的格式
			String data = null;
			try {
				data = new String(body, "utf8");
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
			logger.info("body:{}", data);
			return data;
		}
		return null;
	}
}
